﻿' LibWowArmory
' by Ronald M. Clifford (roncli@roncli.com)
'
' This source code is released under the GNU Library General Public License (LGPL) Version 2.1.

Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Linq
Imports System.Xml.Serialization
Imports System.Web

Namespace roncliProductions.LibWowArmory

    ''' <summary>
    ''' A class that retrieves a character's talents from the Armory
    ''' </summary>
    ''' <remarks></remarks>
    Public Class CharacterTalents
        Inherits WowArmoryData

#Region "Declarations"

        Private ctPage As New CharacterTalentsSchema.page
        Private strRealm As String
        Private strName As String
        Private tPrimary As TalentTree
        Private tSecondary As TalentTree
        Private pPets As New List(Of Pet)
        Private gPrimary As New List(Of Glyph)
        Private gSecondary As New List(Of Glyph)

#End Region

        ''' <summary>
        ''' The realm the character is on
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Realm() As String
            Get
                Return strRealm
            End Get
            Set(ByVal value As String)
                strRealm = value
            End Set
        End Property

        ''' <summary>
        ''' The name of the character
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Name() As String
            Get
                Return strName
            End Get
            Set(ByVal value As String)
                strName = value
            End Set
        End Property

        ''' <summary>
        ''' The URL that will be used to retrieve the character's talents from the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property URL() As String
            Get
                Return String.Format("http://www.wowarmory.com/character-talents.xml?r={0}&n={1}", strRealm, strName)
            End Get
        End Property

        ''' <summary>
        ''' Indicates to the inherited class that this request does not require login
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property RequiresLogin() As Boolean
            Get
                Return False
            End Get
        End Property

        ''' <summary>
        ''' The character's primary talents
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property PrimaryTalents() As TalentTree
            Get
                Return tPrimary
            End Get
        End Property

        ''' <summary>
        ''' The character's secondary talents
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property SecondaryTalents() As TalentTree
            Get
                Return tSecondary
            End Get
        End Property

        ''' <summary>
        ''' The character's pets
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Pets() As List(Of Pet)
            Get
                Return pPets
            End Get
        End Property

        ''' <summary>
        ''' The character's glyphs for their primary talents
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property PrimaryGlyphs() As List(Of Glyph)
            Get
                Return gPrimary
            End Get
        End Property

        ''' <summary>
        ''' The character's glyphs for their secondary talents
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property SecondaryGlyphs() As List(Of Glyph)
            Get
                Return gSecondary
            End Get
        End Property

        ''' <summary>
        ''' The date this character was last modified on the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property LastModified() As Date
            Get
                Return CDate(ctPage.characterInfo.First().character.First().lastModified)
            End Get
        End Property

        ''' <summary>
        ''' A constructor to load a character's talents by realm and character name
        ''' </summary>
        ''' <param name="strRealm"></param>
        ''' <param name="strName"></param>
        ''' <remarks></remarks>
        Public Sub New(ByVal strRealm As String, ByVal strName As String)
            Me.strRealm = strRealm
            Me.strName = strName
            Load()
        End Sub

        ''' <summary>
        ''' Loads the character's talents from the Armory
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Load()
            Dim strKey As String = String.Format("LibWowArmory.CharacterTalents.{0}.{1}", strRealm, strName)
            If Cache.Cache(strKey) Is Nothing Then
                MyBase.Retrieve()

                Dim xsSerializer As New XmlSerializer(ctPage.GetType())

                Dim srXML As New StringReader(MyBase.strData)

                ctPage = CType(xsSerializer.Deserialize(srXML), CharacterTalentsSchema.page)

                Cache.Cache.Insert(strKey, ctPage, Nothing, Date.UtcNow.AddDays(1), Nothing, Caching.CacheItemPriority.Normal, Nothing)
            Else
                ctPage = CType(Cache.Cache(strKey), CharacterTalentsSchema.page)
            End If

            If ctPage Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve talents for does not exist.")
            End If
            If ctPage.characterInfo Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve talents for does not exist.")
            End If
            If ctPage.characterInfo.First().character Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve talents for does not exist.")
            End If
            If ctPage.characterInfo.First().character.First() Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve talents for does not exist.")
            End If
            If ctPage.characterInfo.First().talents Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve talents for does not exist.")
            End If

            Dim strTalents As String

            tPrimary = New TalentTree(CType(ctPage.characterInfo.First().character.First().classId, Enums.ClassType))
            strTalents = ctPage.characterInfo.First().talents.First().talentGroup.Where(Function(tg) tg.group = 1).First().talentSpec.First().value
            For intCount As Integer = 0 To strTalents.Length - 1
                If Not (tPrimary.GetTalentByID(intCount) Is Nothing) Then
                    tPrimary.GetTalentByID(intCount).Points = CInt(strTalents.Chars(intCount).ToString())
                End If
            Next
            gPrimary = (From g In ctPage.characterInfo.First().talents.First().talentGroup.Where(Function(tg) tg.group = 1).First().glyphs.First().glyph Select New Glyph(g.effect, g.icon, g.id, g.name, g.type)).ToList()

            If ctPage.characterInfo.First().talents.First().talentGroup.Count = 2 Then
                tSecondary = New TalentTree(CType(ctPage.characterInfo.First().character.First().classId, Enums.ClassType))
                strTalents = ctPage.characterInfo.First().talents.First().talentGroup.Where(Function(tg) tg.group = 2).First().talentSpec.First().value
                For intcount As Integer = 0 To strTalents.Length - 1
                    If Not (tSecondary.GetTalentByID(intcount) Is Nothing) Then
                        tSecondary.GetTalentByID(intcount).Points = CInt(strTalents.Chars(intcount).ToString())
                    End If
                Next
                gSecondary = (From g In ctPage.characterInfo.First().talents.First().talentGroup.Where(Function(tg) tg.group = 2).First().glyphs.First().glyph Select New Glyph(g.effect, g.icon, g.id, g.name, g.type)).ToList()
            Else
                tSecondary = Nothing
                gSecondary = Nothing
            End If

            If ctPage.characterInfo.First().talents.First().pet Is Nothing Then
                pPets = Nothing
            Else
                Dim strTalentTree As String
                Dim tPet As TalentTree.TalentTree
                For Each pSchemaPet As CharacterTalentsSchema.pet In ctPage.characterInfo.First().talents.First().pet
                    strTalentTree = pSchemaPet.talentGroup.First().prim
                    tPet = New TalentTree(ClassType.Unknown).TalentTrees.Where(Function(tt) tt.Name = strTalentTree).First()
                    strTalents = pSchemaPet.talentGroup.First().talentSpec.First().value
                    For intCount As Integer = 0 To strTalents.Length - 1
                        If tPet.Talents.Count > intCount Then
                            tPet.Talents(intCount).Points = CInt(strTalents.Chars(intCount).ToString())
                        End If
                    Next
                    pPets.Add(New Pet(pSchemaPet.family, pSchemaPet.icon, pSchemaPet.level, pSchemaPet.name, pSchemaPet.npcId, pSchemaPet.npcName, pSchemaPet.talentGroup.First().prim, tPet))
                Next
            End If
        End Sub

        ''' <summary>
        ''' A class that encapsulates a pet
        ''' </summary>
        ''' <remarks></remarks>
        Public Class Pet

            Private strFamily As String
            Private strIcon As String
            Private intLevel As Integer
            Private strName As String
            Private intNPCID As Integer
            Private strNPCName As String
            Private strTalentTree As String
            Private tTalents As TalentTree.TalentTree

            ''' <summary>
            ''' The family of the pet
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property Family() As String
                Get
                    Return strFamily
                End Get
                Set(ByVal value As String)
                    strFamily = value
                End Set
            End Property

            ''' <summary>
            ''' The pet's icon
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property Icon() As String
                Get
                    Return strIcon
                End Get
                Set(ByVal value As String)
                    strIcon = value
                End Set
            End Property

            ''' <summary>
            ''' The pet's level
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property Level() As Integer
                Get
                    Return intLevel
                End Get
                Set(ByVal value As Integer)
                    intLevel = value
                End Set
            End Property

            ''' <summary>
            ''' The pet's name
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property Name() As String
                Get
                    Return strName
                End Get
                Set(ByVal value As String)
                    strName = value
                End Set
            End Property

            ''' <summary>
            ''' The NPC idnetification number of the pet
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property NPCID() As Integer
                Get
                    Return intNPCID
                End Get
                Set(ByVal value As Integer)
                    intNPCID = value
                End Set
            End Property

            ''' <summary>
            ''' The original name of the pet
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property NPCName() As String
                Get
                    Return strNPCName
                End Get
                Set(ByVal value As String)
                    strNPCName = value
                End Set
            End Property

            ''' <summary>
            ''' The name of the pet's talent tree
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property TalentTree() As String
                Get
                    Return strTalentTree
                End Get
                Set(ByVal value As String)
                    strTalentTree = value
                End Set
            End Property

            ''' <summary>
            ''' The pet's talents
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property Talents() As TalentTree.TalentTree
                Get
                    Return tTalents
                End Get
                Set(ByVal value As TalentTree.TalentTree)
                    tTalents = value
                End Set
            End Property

            ''' <summary>
            ''' A constructor to create new pet information
            ''' </summary>
            ''' <param name="strFamily"></param>
            ''' <param name="strIcon"></param>
            ''' <param name="intLevel"></param>
            ''' <param name="strName"></param>
            ''' <param name="intNPCID"></param>
            ''' <param name="strNPCName"></param>
            ''' <param name="strTalentTree"></param>
            ''' <param name="tTalents"></param>
            ''' <remarks></remarks>
            Public Sub New(ByVal strFamily As String, ByVal strIcon As String, ByVal intLevel As Integer, ByVal strName As String, ByVal intNPCID As Integer, ByVal strNPCName As String, ByVal strTalentTree As String, ByVal tTalents As TalentTree.TalentTree)
                Me.strFamily = strFamily
                Me.strIcon = strIcon
                Me.intLevel = intLevel
                Me.strName = strName
                Me.intNPCID = intNPCID
                Me.strNPCName = strNPCName
                Me.strTalentTree = strTalentTree
                Me.tTalents = tTalents
            End Sub

        End Class

        ''' <summary>
        ''' A class that encapsulates a glyph
        ''' </summary>
        ''' <remarks></remarks>
        Public Class Glyph

            Private strEffect As String
            Private strIcon As String
            Private intID As Integer
            Private strName As String
            Private strType As String

            ''' <summary>
            ''' A description of the glyph's effect
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property Effect() As String
                Get
                    Return strEffect
                End Get
                Set(ByVal value As String)
                    strEffect = value
                End Set
            End Property

            ''' <summary>
            ''' The icon of the glyph
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property Icon() As String
                Get
                    Return strIcon
                End Get
                Set(ByVal value As String)
                    strIcon = value
                End Set
            End Property

            ''' <summary>
            ''' The identification number of the glyph
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property ID() As Integer
                Get
                    Return intID
                End Get
                Set(ByVal value As Integer)
                    intID = value
                End Set
            End Property

            ''' <summary>
            ''' The name of the glyph
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property Name() As String
                Get
                    Return strName
                End Get
                Set(ByVal value As String)
                    strName = value
                End Set
            End Property

            ''' <summary>
            ''' The type of glyph, major or minor
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property Type() As String
                Get
                    Return strType
                End Get
                Set(ByVal value As String)
                    strType = value
                End Set
            End Property

            ''' <summary>
            ''' A constructor to create new glyph information
            ''' </summary>
            ''' <param name="strEffect"></param>
            ''' <param name="strIcon"></param>
            ''' <param name="intID"></param>
            ''' <param name="strName"></param>
            ''' <param name="strType"></param>
            ''' <remarks></remarks>
            Public Sub New(ByVal strEffect As String, ByVal strIcon As String, ByVal intID As Integer, ByVal strName As String, ByVal strType As String)
                Me.strEffect = strEffect
                Me.strIcon = strIcon
                Me.intID = intID
                Me.strName = strName
                Me.strType = strType
            End Sub

        End Class

    End Class

End Namespace